package org.nobject.common.js;

import static org.nobject.common.lang.CharUtils.toChars;
import static org.nobject.common.lang.ClassUtils.isBoolean;
import static org.nobject.common.lang.ClassUtils.isChar;
import static org.nobject.common.lang.ClassUtils.isCollection;
import static org.nobject.common.lang.ClassUtils.isDate;
import static org.nobject.common.lang.ClassUtils.isMap;
import static org.nobject.common.lang.ClassUtils.isNumber;
import static org.nobject.common.lang.ClassUtils.isString;
import static org.nobject.common.lang.ObjectUtils.in;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.nobject.common.bean.BeanUtils;
import org.nobject.common.exception.ConvertException;
import org.nobject.common.file.FileUtils;
import org.nobject.common.lang.ByteUtils;
import org.nobject.common.lang.ByteUtils.ASC;
import org.nobject.common.lang.ClassUtils;
import org.nobject.common.lang.ObjectUtils;
import org.nobject.common.lang.StringUtils;

/**
 * JSON工具类<br>
 * 
 * 核心1:JSON字符串到对象的转换(Map,List)
 * 核心2:对象到JSON字符串的转换
 * 
 * 支持键值带双引号的标准格式，同时支持不带双引号的非标准格式，键值引号可以用单引号也可以用双引号
 * 
 * @author bianrongjun
 * @version 1.0
 */
public class JSONUtils2 {

	/******************************************************************************************************************
	 * 
	 *  静态 区域
	 * 
	 *******************************************************************************************************************/
	
	private static Object[] readString(char[] cs,int idx) throws ConvertException{
		StringBuffer sb=new StringBuffer();
		char beginQuot=cs[idx];
		System.out.println("readString:"+idx+","+beginQuot);
		idx++;
		boolean beginSlash=false;
		for(int i=idx;i<cs.length;i++){
			char c=cs[i];
			//System.out.println("readString:"+i+","+c);
			if(!beginSlash&&c==beginQuot){
				return new Object[]{sb.toString(),i};
			}else{
				if(!beginSlash&&c==ASC.slash_r){
					beginSlash=true;
				}else{
					sb.append(c);
					beginSlash=false;
				}
			}
		}
		throw new ConvertException("String格式化无法识别");
	}
	
	private static Object[] readNum(char[] cs,int idx) throws ConvertException{
		boolean doubleNum	=false;
		boolean start		=false;
		StringBuffer sb=new StringBuffer();
		if(cs[idx]=='+'||cs[idx]=='-'){
			sb.append(cs[idx]);
			idx++;
		}
		for(int i=idx;i<cs.length;i++){
			char c=cs[i];
			
			if(!doubleNum&&c==ASC.dot){
				if(!start) throw new ConvertException("格式错误");
				doubleNum=true;
				sb.append(c);
				continue;
			}
			
			if(c>='0'&&c<='9'){
				sb.append(c);
				if(!start) start=true;
			}else{
				Object o=null;
				if(doubleNum){
					o=Double.parseDouble(sb.toString());
				}else{
					o=Integer.parseInt(sb.toString());
				}
				return new Object[]{o,i-1};
			}
		}
		
		throw new ConvertException("Num格式化无法识别");
	}
	
	private static Character[] emptyChars=new Character[] { (char)ASC.cr, (char)ASC.lf, (char)ASC.space, (char)ASC.tab };
	
	private static boolean isEmpty(char c){
		return ObjectUtils.in(c,emptyChars);
	}
	
	private static Object[] read(char[] cs,int idx) throws ConvertException{
		for(int i=idx;i<cs.length;i++){
			char c=cs[i];
			System.out.println("read:"+i+","+c);
			if(isEmpty(c)) continue;
			
			if(c==ASC.bracket_l)							return readArray(cs, i);
			else if(c==ASC.brace_l)							return readObject(cs, i);
			else if(c==ASC.quot_d||c==ASC.quot_s)			return readString(cs, i);
			else if(('0'<= c&& c <='9')||c=='+'||c=='-')	return readNum(cs, i);
			else{
				if (c == 'n') {
					if (i+3<cs.length||new String(cs,i,3).equals("null")) return readNull(cs, i);
				} else if(c=='t'||c=='f') {
					if ((i+3<cs.length&&new String(cs,i,4).equals("true"))
					  ||(i+4<cs.length&&new String(cs,i,5).equals("false"))){
						return readBoolean(cs, i);
					}
				}
			}
		}
		throw new ConvertException("格式化无法识别");
	}
	
	private static Object[] readNull(char[] cs,int idx){
		return new Object[]{null,idx+3};
	}
	
	private static Object[] readArray(char[] cs,int idx) throws ConvertException{
		List l=new LinkedList();
		STATUS status 			= STATUS.begin;
		
		for(int i=idx;i<cs.length;i++){
			char c=cs[i];
			//System.out.println("readArray:"+i+","+c);
			switch (status) {
				case begin:
					if(c == ASC.bracket_l){
						status=STATUS.partBegin;
						continue;
					}
				case partBegin:
					if(isEmpty(c)) continue;
					if(c== ASC.bracket_r){
						status=STATUS.end;
						continue;
					}else{
						Object[] o=read(cs, i);
						i=(Integer)o[1];
						l.add(o[0]);
						status=STATUS.partEnd;
						continue;
					}
				case partEnd:
					if(isEmpty(c)) continue;
					if(c==ASC.comma){
						status=STATUS.partBegin;
						continue;
					}
				case end:
					return new Object[]{l,i-1};
			}
		}
		
		throw new ConvertException("List转换格式有误");
	}
	
	private static Object[] readObject(char[] cs,int idx) throws ConvertException{
		Map o=new HashMap();
		int nIdx=idx;
		StringBuffer sb_key=new StringBuffer();
		boolean withKeyQuot=false;
		char keyQuot=(char)ASC.quot_d;
		STATUS status 			= STATUS.begin;
		
		for(int i=idx;i<cs.length;i++){
			char c=cs[i];
			System.out.println("readObject:"+i+","+c);
			switch (status) {
				case begin:
					if(c == ASC.brace_l){
						status=STATUS.partBegin;
						continue;
					}
				case partBegin:
					if(isEmpty(c)) continue;
					if(c== ASC.brace_r){
						status=STATUS.end;
						continue;
					}else if(('a'<=c&&c<='z')||('A'<=c&&c<='Z')||c =='_'||c=='$'||c==ASC.quot_d||c==ASC.quot_s){
						status=STATUS.keyBegin;
						if(c==ASC.quot_d||c==ASC.quot_s){
							withKeyQuot=true;
							keyQuot=c;
						}else{
							sb_key.append(c);
						}
						continue;
					}
				case keyBegin:
					if(('a'<=c&&c<='z')||('A'<= c&&c<= 'Z')||c=='_'||c=='$'||(c>='0'&&c<='9')){
						sb_key.append(c);
					}else if(c==keyQuot){
						status=STATUS.keyEnd;
					}else if(isEmpty(c)){
						if(withKeyQuot) throw new ConvertException("未匹配键引号:"+c);
						status=STATUS.keyEnd;
					}else{
						throw new ConvertException("非键值可用字符:"+c);
					}
					continue;
				case keyEnd:
					if(isEmpty(c)) continue;
					else if(c==ASC.colon){
						status=STATUS.valueBegin;
						
						continue;
					}
				case valueBegin:
					if(isEmpty(c)) continue;
					else{
						Object[] vo=read(cs, i);
						o.put(sb_key.toString(), vo[0]);
						i=(Integer)vo[1];
						status=STATUS.partEnd;
					}
				case partEnd:
					if(isEmpty(c)) continue;
					if(c==ASC.comma){
						status=STATUS.partBegin;
						continue;
					}else if(c== ASC.brace_r){
						status=STATUS.end;
						continue;
					}
				case end:
					return new Object[]{o,i-1};
			}
		}
		
		return new Object[]{o,nIdx};
	}
	
	private static Object[] readBoolean(char[] cs,int idx){
		boolean t=cs[idx]=='t';
		int c=t?3:4;
		return new Object[]{t,idx+c};
	}
	
	public static List toList2(String str) throws ConvertException{
		return (List)readArray(str.toCharArray(), 0)[0];
	}
	
	public static void main(String[] args) throws Exception{
		
//		System.out.println(false?Double.parseDouble("1.0"):Integer.parseInt("1"));
		
		String s=FileUtils.read2String("c:/a.txt");
		JSONArray jo=new JSONArray(toList2(s));
		System.out.println(jo.toString());
	}
	
//	public static String readFunction(char[] cs,int idx){
//		StringBuffer sb=new StringBuffer();
//		int nIdx=idx;
//		return new Object[]{sb.toString(),nIdx};
//	}
	
	/** 
	 * 对象转换为JSON格式字符串
	 * @param obj 对象
	 */
	public static String toString(Object obj) {
		if(obj==null) return "null";
		StringBuffer sb = new StringBuffer();
		Class clazz = obj.getClass();
		if (clazz.isArray()) {
			Object []oo=(Object [])obj;
			sb.append("[");
			for (int i = 0;i< oo.length; i++) {
				if(i!=0) sb.append(",");
				sb.append(toString(oo[i]));
			}
			sb.append("]");
		}else if (isMap(clazz)) {
			Map m = (Map) obj;
			sb.append("{");
			for (Iterator iterator = m.keySet().iterator(); iterator.hasNext();) {
				String key = (String) iterator.next();
				sb.append("\"").append(key).append("\"").append(":").append(toString(m.get(key)));
				if (iterator.hasNext()) sb.append(",");
			}
			sb.append("}");
		} else if (isCollection(clazz)) {
			Collection l = (Collection) obj;
			sb.append("[");
			for (Iterator iterator = l.iterator(); iterator.hasNext();) {
				sb.append(toString(iterator.next()));
				if (iterator.hasNext()) sb.append(",");
			}
			sb.append("]");
		} else if (isString(clazz)) {
			sb.append("\"")
				.append(((String)obj)
						.replaceAll("\\\\","\\\\\\\\")
						.replaceAll("\"","\\\\\"")
						.replaceAll("\r","\\\\r")
						.replaceAll("\n","\\\\n"))
				.append("\"");
		} 
		else if (isNumber(clazz)) 	sb.append(StringUtils.toString((Number)obj));
		else if (isBoolean(clazz)) 	sb.append(StringUtils.toString((Boolean)obj));
		else if (isDate(clazz)) 	sb.append(StringUtils.toString((Date)obj));
		else if (isChar(clazz)) 	sb.append(StringUtils.toString((Character)obj));
		else if (JSONArray.class.isAssignableFrom(clazz)||JSONObject.class.isAssignableFrom(clazz)) sb.append(obj.toString());
		else {
			Field[] fields=ClassUtils.getFields(clazz);
			sb.append("{");
			boolean has=false;
			for (Field field:fields) {
				String propName = field.getName();
				try {
					Method method = (Method) BeanUtils.getGetMethod(obj.getClass(), propName);
					if(method!=null){
						if(has) sb.append(",");
						has=true;
						sb.append("\""+propName+"\"").append(":");
						Object ro = method.invoke(obj);
						if (ro == null)  sb.append("null");
						else sb.append(toString(ro));
					}
				} catch (Exception e) {
					throw new RuntimeException("不该发生的异常:"+e.getMessage());
				}
			}
			sb.append("}");
		}
		return sb.toString();
	}
	
	/**
	 * 字符串转换成JSON数组
	 * @param str 字符串
	 */
	public static List toList(String str) 				throws ConvertException{return  new JSONUtils2(true)._toList(str);}

	/**
	 * 字符串转换成JSON对象
	 * @param str 字符串
	 */
	public static Map toMap(String str) 				throws ConvertException{return new JSONUtils2(true)._toMap(str);}
	
	/** 
	 * 字符串转换为JSONObject
	 * @param str 字符串
	 */
	public static JSONObject toJSONObject(String str) 	throws ConvertException{return new JSONObject(JSONUtils2.toMap(str));}
	
	/** 
	 * 字符串转换为JSONArray
	 * @param str 字符串
	 */
	public static JSONArray toJSONArray(String str) 	throws ConvertException{return new JSONArray(JSONUtils2.toList(str));}
	
	
	
	////////////////////////////////////////////////////////////////////
	/////////////////////        方法         /// ////////////////////////////
	////////////////////////////////////////////////////////////////////
	
	
	/** useMapList */
	private boolean useMapList=false;
	
	/** 构造函数  */
	private JSONUtils2(){}
	
	/**
	 * 构造函数 
	 * @param useMapList
	 */
	private JSONUtils2(boolean useMapList){this.useMapList=useMapList;}
	
	/******************************************************************************************************************
	 * 
	 *  非静态 区域
	 * 
	 *******************************************************************************************************************/
	
	/** 元素MAP */
	private Map eles 				= null;
	/** objs */
	private List objs 				= null;
	/** 块类型 */
	private PTYPE ptype 			= PTYPE.init;
	/** 状态 */
	private STATUS status 			= STATUS.partBegin;
	/** 块值 */
	private StringBuffer pvalue 	= new StringBuffer();
	/** 块键值 */
	private StringBuffer pkey 		= new StringBuffer();
	/** 上一块保存 */
	private boolean lastPartSaved 	= true;
	/** 是浮点 */
	private boolean isDoubleNumber 	= false;
	/** 是带符号 */
	private boolean isSingedNumber 	= false;
	/** 开始斜杠 */
	private boolean beginSlashR 	= false;
	/** 开始引号 */
	private boolean beginQuot 		= false;
	/** 引号类型(默认') */
	private char quotChar			=(char)ByteUtils.ASC.quot_s;
	/** 子级 */
	private int childLevel 			= 0;
	
	/** 状态 */
	private enum STATUS {
		begin, partBegin, keyBegin, keyEnd, valueBegin, valueMiddle, valueEnd, partMiddle, partEnd, end
	}
	/** 块类型 */
	private enum PTYPE {
		init, nvll, string, num, object, array, date, bool
	}
	
	/**
	 * 字符串转换成JSON数组
	 * @param str 字符串
	 */
	private List _toList(String str) throws ConvertException{
		objs = new LinkedList();
		str = getOffBracket(str.trim());
		
		if (StringUtils.isEmpty(str)) return objs;
		
		char[] cs = toChars(str);
		for (int i = 0; i < cs.length; i++) {
			System.out.println("<"+status+">"+i+":"+cs[i]);
			switch (status) {
			case partBegin:			// 块开始
			case partEnd:			// 块结束
				//忽略空字符
				if (in(cs[i], new Character[] { (char)ASC.cr, (char)ASC.lf, (char)ASC.space, (char)ASC.tab })) continue;
				if (cs[i] == ASC.comma) {								// 逗号
					if (status == STATUS.partBegin) 	throw new ConvertException("JSON格式化错误:PART_BEGIN  can't start with comma");
					if (status == STATUS.partEnd) {
						if (lastPartSaved) 				throw new ConvertException("JSON格式化错误:PART_END  can't save before comma");
						doPartSave();
						continue;
					}
				}
				if (lastPartSaved == false) 			throw new ConvertException("JSON格式化错误:PART_END  lastPartSaved hadn't been saved");
				if (cs[i] == ASC.quot_s || cs[i] == ASC.quot_d) {		// 字串
					beginQuot = true;
					quotChar = cs[i];
					ptype = PTYPE.string;
				} else if (('0' <= cs[i] && cs[i] <= '9') || cs[i] == '+' || cs[i] == '-') {// 数字
					i--;
					ptype = PTYPE.num;
				} else if (cs[i] == ASC.bracket_l) {										// 数组
					i--;
					ptype = PTYPE.array;
				} else if (cs[i] == ASC.brace_l) {											// 对象
					i--;
					ptype = PTYPE.object;
				} else {																	// 特殊对象
					if (cs[i] == 'n') {
						if (i + 3 < cs.length || new String(cs, i, 3).equals("null")) {
							i--;
							ptype = PTYPE.nvll;
						} else throw new ConvertException("JSON格式化错误:PART_END unknow char from bs[" + i + "] to end");
					} else if (cs[i] == 't' || cs[i] == 'f') {
						if (i + 3 < cs.length && new String(cs, i, 4).equals("true")) {
							i--;
							ptype = PTYPE.bool;
						} else if (i + 4 < cs.length && new String(cs, i, 5).equals("false")) {
							i--;
							ptype = PTYPE.bool;
						} else throw new ConvertException("JSON格式化错误:PART_END unknow char from bs[" + i + "] to end");
					}else throw new ConvertException("JSON格式化错误:PART_END next char is ["+i+"]:" + (char) cs[i]);
				}
				status = STATUS.partMiddle;
				lastPartSaved = false;
				continue;
			case partMiddle:
				if (ptype == PTYPE.string) {							// 字串
					if (!beginSlashR) {
						if (cs[i] == ASC.slash_r) beginSlashR = true;
						else {
							if (cs[i] == quotChar) status = STATUS.partEnd;
							else pvalue.append(cs[i]);
						}
					} else {
						pvalue.append(cs[i]);//[pvalue.append(ByteUtils.convertSlashSpecialChar((char) cs[i]));
						beginSlashR = false;
					}
					continue;
				} else if (ptype == PTYPE.num) {						// 数字
					if (!isSingedNumber && (cs[i] == '+' || cs[i] == '-')) {
						isSingedNumber = true;
						pvalue.append(cs[i]);
						continue;
					}
					
					if (isSingedNumber && (cs[i] == '+' || cs[i] == '-')) throw new ConvertException("JSON格式化错误:SingedNumber must has only one sign char");

					if (isSingedNumber && pvalue.length() == 1 && !('0' <= cs[i] && cs[i] <= '9')) throw new ConvertException("JSON格式化错误:SingerNumber can't without number ");

					if ('0' <= cs[i] && cs[i] <= '9') {
						pvalue.append(cs[i]);
					} else if (cs[i] == ASC.dot) {
						if (isDoubleNumber) throw new ConvertException("JSON格式化错误:FloatNumber can't has more than one dot ");
						else {
							pvalue.append(cs[i]);
							isDoubleNumber = true;
						}
					} else if (cs[i] == ASC.space) {
						status = STATUS.partEnd;continue;
					} else if (cs[i] == ASC.comma) {
						status = STATUS.partEnd;i--;continue;
					}
				} else if (ptype == PTYPE.bool) {						// 布尔
					if (i + 3 < cs.length && new String(cs, i, 4).equals("true")) {
						i += 3;
						pvalue.append("true");
					} else if (i + 4 < cs.length && new String(cs, i, 5).equals("false")) {
						i += 4;
						pvalue.append("false");
					} else {
						throw new ConvertException("JSON格式化错误:Boole impossble error ");
					}
					status = STATUS.partEnd;
				} else if (ptype == PTYPE.array) {						// 数组
					if (beginSlashR) {
						pvalue.append(cs[i-1]).append(cs[i]);
						continue;
					}

					if (cs[i] == ASC.bracket_l) {
						childLevel++;
						pvalue.append(cs[i]);
					} else if (cs[i] == ASC.bracket_r) {
						childLevel--;
						pvalue.append(cs[i]);
						
						if(!beginSlashR && !beginQuot && childLevel == 0){
							status = STATUS.partEnd;
							continue;
						}
						
					} else if (cs[i] == ASC.slash_r) {
						beginSlashR = true;
					} else {
						pvalue.append(cs[i]);
					}
					continue;

				} else if (ptype == PTYPE.object) {// 对象
					if (beginSlashR) {
						pvalue.append(cs[i-1]).append(cs[i]);//此时因为要再次解析需要带上右斜杠
						beginSlashR = false;
						continue;
					}

					if (cs[i] == ASC.brace_l) {
						childLevel++;
						pvalue.append(cs[i]);
					} else if (cs[i] == ASC.brace_r) {
						childLevel--;
						pvalue.append(cs[i]);
						
						if(!beginSlashR && !beginQuot && childLevel == 0){
							status = STATUS.partEnd;
							continue;
						}
						
					} else if (cs[i] == ASC.slash_r) {
						beginSlashR = true;
					} else {
						pvalue.append(cs[i]);
					}
				} else if (ptype == PTYPE.nvll) {// NULL
					i += 3;
					status = STATUS.partEnd;
				}
				break;
			default:
				break;
			}

		}
		if (status == STATUS.partMiddle) status = STATUS.end;
		if (lastPartSaved == false) doPartSave();
		return objs;
	}
 
	/** 
	 * 完成一个段落时保存值
	 */
	private void doPartSave() throws ConvertException{
		String sPValue=pvalue.toString();
		String sPkey=pkey.toString();
		if (objs != null) {
			switch (ptype) {
			case string:objs.add(sPValue);break;
			case num:
				if (isDoubleNumber) objs.add(Double.valueOf(sPValue));
				else objs.add(Integer.valueOf(sPValue));//TODO LONG转换判断
				break;
			case array:objs.add(useMapList?toList(sPValue):JSONArray.toJSONArray(_toList(sPValue)));break;
			case date:break;//TODO 时间转换
			case object:objs.add(useMapList?toMap(sPValue):JSONObject.toJSONObject(toMap(sPValue)));break;
			case nvll:objs.add(null);break;
			case bool:objs.add(Boolean.valueOf(sPValue));break;
			}
		} else if (eles != null) {
			switch (ptype) {
			case string:eles.put(sPkey, sPValue);break;
			case num:
				if (isDoubleNumber) eles.put(sPkey, Double.valueOf(sPValue));
				else eles.put(sPkey, Integer.valueOf(sPValue));//TODO LONG转换判断
				break;
			case array: eles.put(sPkey, useMapList?toList(sPValue):JSONArray.toJSONArray(_toList(sPValue)));break;
			case date:break;//TODO 时间转换
			case object:eles.put(sPkey, useMapList?toMap(sPValue):JSONObject.toJSONObject(toMap(sPValue)));break;
			case nvll:eles.put(sPkey, null);break;
			case bool:eles.put(sPkey, Boolean.valueOf(sPValue));break;
			}
		} else {
			throw new ConvertException("JSON格式化错误:error type call");
		}
		beginSlashR = false;
		isDoubleNumber = false;
		isSingedNumber = false;
		beginQuot = false;
		quotChar = (char)ASC.quot_s;
		childLevel = 0;
		lastPartSaved = true;
		pkey = new StringBuffer();
		pvalue = new StringBuffer();
	}

	/**
	 * 字串对象变JSON对象Map
	 * 
	 * @param str 字串
	 */
	private Map _toMap(String str) throws ConvertException, ConvertException{
		eles = new LinkedHashMap();
		str = getOffBrace(str.trim());
		if(StringUtils.isEmpty(str)) return eles;
		
		//byte[] cs = str.getBytes();
		char[] cs = new char[str.length()];
		str.getChars(0, str.length(), cs, 0);
		
		for (int i = 0; i < cs.length; i++) {
			//System.out.println("<"+status+">"+i+":"+cs[i]);
			switch (status) {
			case end:
			case partBegin:			// 块开始
			case partEnd:			// 块结束
				if (in(cs[i], new Character[] { (char)ASC.cr, (char)ASC.lf, (char)ASC.space,(char)ASC.tab })) continue;
				if (cs[i] == ASC.comma) {							// 逗号
					if (status == STATUS.partBegin){throw new ConvertException("JSON格式化错误:PART_BEGIN :开头不能为逗号");}
					if (status == STATUS.partEnd) {
						if (lastPartSaved){throw new ConvertException("JSON格式化错误:PART_END :上段已保存,错误字符 逗号");}
						doPartSave();
						continue;
					}
				} else if (cs[i] == ASC.quot_d||cs[i] == ASC.quot_s) {//带引号键值模式
					status = STATUS.keyBegin;
					quotChar=cs[i];
					continue;
				} else if (('a' <= cs[i] && cs[i] <= 'z') || ('A' <= cs[i] && cs[i] <= 'Z') || cs[i] == '_' || cs[i] == '$') {
					pkey.append(cs[i]);
					status = STATUS.keyBegin;
					continue;
				} else {
					throw new ConvertException("JSON格式化错误:段落结束:键值不能以" +(i>0?cs[i-1]:"")+ cs[i]+"("+i+")开头");
				}
				continue;
			case keyBegin:// 块头
				if (('a' <= cs[i] && cs[i] <= 'z') || ('A' <= cs[i] && cs[i] <= 'Z') || cs[i] == '_' || cs[i] == '$' || ('0' <= cs[i] && cs[i] <= '9')) {
					pkey.append(cs[i]);
					continue;
				}else if(cs[i] == quotChar){
					status = STATUS.keyEnd;
				} else if (cs[i] == ASC.space) {
					status = STATUS.keyEnd;
				} else if (cs[i] == ASC.colon) {
					status = STATUS.valueBegin;
				} else {
					throw new ConvertException("JSON格式化错误:KEY_BEGIN key can't have char:" + (char) cs[i]);
				}
				continue;
			case keyEnd:// 块头
				if (cs[i] == ASC.space) {
					continue;
				} else if (cs[i] == ASC.colon) {
					status = STATUS.valueBegin;
					continue;
				} else{
					throw new ConvertException("JSON格式化错误:KEY_BEGIN key can't have char:" + (char) cs[i]);
				}
			case valueBegin:
				if (cs[i] == ASC.space) {
					continue;
				} else if (cs[i] == ASC.quot_s || cs[i] == ASC.quot_d) {// 字串
					beginQuot = true;
					quotChar = cs[i];
					ptype = PTYPE.string;
				} else if (('0' <= cs[i] && cs[i] <= '9') || cs[i] == '+' || cs[i] == '-') {// 数字
					i--;
					ptype = PTYPE.num;
				} else if (cs[i] == ASC.bracket_l) {// 数组
					ptype = PTYPE.array;
					childLevel++;
					pvalue.append(cs[i]);
				} else if (cs[i] == ASC.brace_l) {// 对象
					ptype = PTYPE.object;
				} else {// 特殊对象
					if (cs[i] == 'n') {
						if (i + 3 < cs.length || new String(cs, i, 3).equals("null")) {
							i--;
							ptype = PTYPE.nvll;
						} else {
							throw new ConvertException("JSON格式化错误:VALUE_BEGIN unknow char from bs[" + i + "] to end");
						}
					} else if (cs[i] == 't' || cs[i] == 'f') {
						if (i + 3 < cs.length && new String(cs, i, 4).equals("true")) {
							i--;
							ptype = PTYPE.bool;
						} else if (i + 4 < cs.length && new String(cs, i, 5).equals("false")) {
							i--;
							ptype = PTYPE.bool;
						} else {
							throw new ConvertException("JSON格式化错误:VALUE_BEGIN unknow char from bs[" + i + "] to end");
						}
					} else {
						throw new ConvertException("JSON格式化错误:VALUE_BEGIN next char ["+i+"] is " + cs[i] + ":" + (char) cs[i]);
					}
				}
				status = STATUS.valueMiddle;
				lastPartSaved = false;

				continue;
			case valueMiddle:
				if (ptype == PTYPE.string) {// 字串
					if (!beginSlashR) {
						if (cs[i] == ASC.slash_r) {
							beginSlashR = true;
						} else {
							if (cs[i] == quotChar) {
								status = STATUS.partEnd;
							} else {
								pvalue.append(cs[i]);
							}
						}
					} else {
						pvalue.append(cs[i]);
						//pvalue.append(ByteUtils.convertSlashSpecialChar((char) cs[i]));
						beginSlashR = false;
					}
					continue;
				} else if (ptype == PTYPE.num) {// 数字

					if (!isSingedNumber && (cs[i] == '+' || cs[i] == '-')) {
						isSingedNumber = true;
						pvalue.append(cs[i]);
						continue;
					}

					if (isSingedNumber && (cs[i] == '+' || cs[i] == '-')) {
						throw new ConvertException("JSON格式化错误:SingedNumber must has only one sign char");
					}

					if (isSingedNumber && pvalue.length() == 1 && !('0' <= cs[i] && cs[i] <= '9')) {
						throw new ConvertException("JSON格式化错误:SingerNumber can't without number ");
					}

					if ('0' <= cs[i] && cs[i] <= '9') {
						pvalue.append(cs[i]);
					} else if (cs[i] == ASC.dot) {
						if (isDoubleNumber) {
							throw new ConvertException("JSON格式化错误:FloatNumber can't has more than one dot ");
						} else {
							pvalue.append(cs[i]);
							isDoubleNumber = true;
						}
					} else if (cs[i] == ASC.space) {
						status = STATUS.partEnd;
						continue;
					} else if (cs[i] == ASC.comma) {
						i--;
						status = STATUS.partEnd;
						continue;
					}
				} else if (ptype == PTYPE.bool) {// 布尔
					if (i + 3 < cs.length && new String(cs, i, 4).equals("true")) {
						i += 3;
						pvalue.append("true");
					} else if (i + 4 < cs.length && new String(cs, i, 5).equals("false")) {
						i += 4;
						pvalue.append("false");
					} else {
						throw new ConvertException("JSON格式化错误:Boole impossble error ");
					}
					status = STATUS.partEnd;
				} else if (ptype == PTYPE.array) {// 数组

					if (beginSlashR) {
						pvalue.append(cs[i-1]).append(cs[i]);//pvalue.append(ByteUtils.convertSlashSpecialChar((char) cs[i]));
						continue;
					}

					if (cs[i] == ASC.bracket_l) {
						childLevel++;
						pvalue.append(cs[i]);
					} else if (cs[i] == ASC.bracket_r) {
						//System.out.println("遇到1次:"+childLevel);
						childLevel--;
						pvalue.append(cs[i]);
						
						if (!beginSlashR && !beginQuot && childLevel == 0 && cs[i] == ASC.bracket_r) {
							//System.out.println("pvalue:"+pvalue);
							status = STATUS.partEnd;
							continue;
						}
						
					} else if (cs[i] == ASC.slash_r) {
						beginSlashR = true;
					} else {
						pvalue.append(cs[i]);
					}
					continue;

				} else if (ptype == PTYPE.object) {// 对象
					if (!beginSlashR && !beginQuot && childLevel == 0 && cs[i] == ASC.brace_r) {status = STATUS.partEnd;continue;}
					if (beginSlashR){
						pvalue.append(cs[i-1]).append(cs[i]);//pvalue.append(ByteUtils.convertSlashSpecialChar((char) cs[i]));
						continue;
					}

					if (cs[i] == ASC.brace_l) {childLevel++;pvalue.append(cs[i]);} 
					else if (cs[i] == ASC.brace_r) {childLevel--;pvalue.append(cs[i]);} 
					else if (cs[i] == ASC.slash_r) {beginSlashR = true;} 
					else {pvalue.append(cs[i]);}
					
				} else if (ptype == PTYPE.nvll) {// NULL
					i += 3;status = STATUS.partEnd;
				}
				break;
			default: break;
			}
		}

		if (status == STATUS.partMiddle) status = STATUS.end;

		if (lastPartSaved == false) doPartSave();

		return eles;
	}

	/**
	 * 去掉左右方括号[]
	 * @param str
	 */
	private String getOffBracket(String str) {
		if (str.length()>0&&str.charAt(0) == ASC.bracket_l && str.charAt(str.length() - 1) == ASC.bracket_r) {
			str = str.substring(1, str.length() - 1);
		}
		return str;
	}

	/**
	 * 去掉左右大括号{}
	 * @param str
	 */
	private String getOffBrace(String str) {
		if (str.length() >= 2 && str.charAt(0) == ASC.brace_l && str.charAt(str.length() - 1) == ASC.brace_r) {
			str = str.substring(1, str.length() - 1);
		}
		return str;
	}


}